package la.iok.hzsvn.lewin.movie.cloud.service;

import la.iok.hzsvn.lewin.movie.cloud.entity.OrgUnit;
import la.iok.hzsvn.lewin.movie.core.RoleEnum;
import la.iok.hzsvn.lewin.movie.core.Token;
import la.iok.hzsvn.share.annotations.NotNull;
import la.iok.hzsvn.share.annotations.NotNullElement;
import la.iok.hzsvn.share.annotations.Nullable;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class DashBoardServiceImpl implements DashBoardService{
    private final OrgUnitService orgUnitService;
    private final UserRoleService userRoleService;
    private final UserService userService;
    private final DeviceService deviceService;
    private final RoomService roomService;

    public DashBoardServiceImpl(OrgUnitService orgUnitService,
                                UserRoleService userRoleService,
                                UserService userService,
                                DeviceService deviceService,
                                RoomService roomService) {
        this.orgUnitService = orgUnitService;
        this.userRoleService = userRoleService;
        this.userService = userService;
        this.deviceService = deviceService;
        this.roomService = roomService;
    }

    @Override
    public int userTotalCount(@NotNull Token token, @Nullable Long orgUnitId) {
        if(token.hasAuthority(RoleEnum.Admin)){
            if(orgUnitId != null){
                Set<Long> orgUnitIds = totalOrgUnitIds(orgUnitId);
                return userRoleService.userCount(orgUnitIds);
            }else{
                return userService.count();
            }
        }else{
            Set<Long> orgUnitIds = totalOrgUnitIds(token.getOrgUnitId());
            if(orgUnitId != null){
                if(!orgUnitIds.contains(orgUnitId)){
                    // 没有orgUnitId的访问权限
                    return 0;
                }
                if(orgUnitIds.size() > 1){
                    //用户所在组织是加盟商,并且加盟商还有其他店铺。并且查询的就是加盟商的所有用户,那应该包含加盟商及其管理的所有店铺中的用户
                    if(Objects.equals(orgUnitId,token.getOrgUnitId())){
                        return userRoleService.userCount(orgUnitIds);
                    }else{
                       //orgUnitId只是操作用户管理的一个店铺
                        return userRoleService.userCount(Collections.singleton(orgUnitId));
                    }
                }else{
                    //操作用户在一个店铺中,只能看这一个店铺的用户
                    return userRoleService.userCount(orgUnitIds);
                }
            }else{
                return userRoleService.userCount(orgUnitIds);
            }
        }
    }

    @Override
    public int deviceTotalCount(@NotNull Token token, @Nullable Long orgUnitId) {
        if(token.hasAuthority(RoleEnum.Admin)){
            if(orgUnitId == null){
                return deviceService.count();
            }else{
                return deviceService.count("orgUnitId",totalOrgUnitIds(orgUnitId));
            }
        }else{
            Set<Long> allOrgUnitIds = totalOrgUnitIds(token.getOrgUnitId());
            if(orgUnitId == null){
                return deviceService.count("orgUnitId",allOrgUnitIds);
            }else{
                if(!allOrgUnitIds.contains(orgUnitId)){
                    return 0;
                }
                if(Objects.equals(orgUnitId,token.getOrgUnitId())){
                    return deviceService.count("orgUnitId",allOrgUnitIds);
                }else{
                    return deviceService.count("orgUnitId",Collections.singleton(orgUnitId));
                }
            }
        }
    }

    @Override
    public int orgUnitTotalCount(@NotNull Token token, @Nullable Long orgUnitId, @Nullable Integer type) {
        if(token.hasAuthority(RoleEnum.Admin)){
            if(orgUnitId == null){
                return orgUnitService.count(type);
            }else{
                return orgUnitService.count(orgUnitId,type);
            }
        }else{
            if(orgUnitId == null){
                return orgUnitService.count(token.getOrgUnitId(),type);
            }else{
                return orgUnitService.count(token.getOrgUnitId(),orgUnitId,type);
            }
        }
    }

    @Override
    public int roomTotalCount(@NotNull Token token, @Nullable Long orgUnitId) {
        if(token.hasAuthority(RoleEnum.Admin)){
            if(orgUnitId == null){
                return roomService.count();
            }else{
                return roomService.count("orgUnitId",totalOrgUnitIds(orgUnitId));
            }
        }else{
            Set<Long> allOrgUnitIds = totalOrgUnitIds(token.getOrgUnitId());
            if(orgUnitId == null){
                return roomService.count("orgUnitId",allOrgUnitIds);
            }else{
                if(!allOrgUnitIds.contains(orgUnitId)){
                    return 0;
                }
                if(Objects.equals(orgUnitId,token.getOrgUnitId())){
                    return roomService.count("orgUnitId",allOrgUnitIds);
                }else{
                    return roomService.count("orgUnitId",Collections.singleton(orgUnitId));
                }
            }
        }
    }

    @NotNull
    @NotNullElement
    public Set<Long> totalOrgUnitIds(@Nullable Long orgUnitId){
        if(orgUnitId == null){
            return Collections.emptySet();
        }
        List<OrgUnit> orgUnits = orgUnitService.listByProperty("parentId",orgUnitId);
        Set<Long> orgUnitIds = orgUnits.stream().map(OrgUnit::getId).collect(Collectors.toSet());
        orgUnitIds.add(orgUnitId);
        return orgUnitIds;
    }
}
